/*
 * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_UTILITIES_COMPILERWARNINGS_VISCPP_HPP
#define SHARE_UTILITIES_COMPILERWARNINGS_VISCPP_HPP

#define PRAGMA_DISABLE_MSVC_WARNING(num) _Pragma(STR(warning(disable : num)))

#define PRAGMA_DIAG_PUSH _Pragma("warning(push)")
#define PRAGMA_DIAG_POP  _Pragma("warning(pop)")

// The Visual Studio implementation of FORBID_C_FUNCTION explicitly does
// nothing, because there doesn't seem to be a way to implement it for Visual
// Studio.  What seems the most likely approach is to use deprecation warnings,
// but that runs into problems.
//
// (1) Declaring the function deprecated (using either __declspec(deprecated)
// or the C++14 [[deprecated]] attribute) fails with warnings like this:
//   warning C4273: 'exit': inconsistent dll linkage
// It seems attributes are not simply additive with this compiler.
//
// (2) Additionally adding __declspec(dllimport) to deal with (1) fails with
// warnings like this:
//   error C2375: 'vsnprintf': redefinition; different linkage
// It seems some functions in the set of interest have different linkage than
// others ("exit" is marked imported while "vsnprintf" is not, for example).
// That makes it difficult to provide a generic macro.
//
// (3) Using __pragma(deprecated(name)) fails with
//   warning C4995: 'frobnicate': name was marked as #pragma deprecated
// for a *declaration* (not a use) of a 'frobnicate' function.
//
// ALLOW_C_FUNCTIONS disables deprecation warnings over the statement scope.
// Some of the functions we're interested in allowing are conditionally
// deprecated on Windows, under the control of various preprocessor defines
// such as _CRT_SECURE_NO_WARNINGS.  Annotating vetted uses allows those
// warnings to catch unchecked uses.

#define FORBID_C_FUNCTION(signature, alternative)

#define ALLOW_C_FUNCTION(name, ...)             \
  PRAGMA_DIAG_PUSH                              \
  PRAGMA_DISABLE_MSVC_WARNING(4996)             \
  __VA_ARGS__                                   \
  PRAGMA_DIAG_POP

#endif // SHARE_UTILITIES_COMPILERWARNINGS_VISCPP_HPP
